home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-09 | 12.7 KB | 511 lines | [TEXT/MSET] |
- \ Sept 92 mrh New words etc. moving closer to ANSI standard
- \ Jul 93 mrh Select{ removed - replaced by Select[ in caseMod
-
- false value ECHO? \ echo load to screen?
-
- cr .( loading Base...)
-
- \ (* ... *) defines a multi-line comment, which can be very useful. Many
- \ Pascal compilers use these symbols - I thought it better not to use
- \ the C-style /* ... */ since */ already has a meaning.
- \ A useful improvement to the typical Pascal implementation is to keep a
- \ level count so that this kind of comment can be nested.
-
- : (*
- 1 \ initial level count
- BEGIN
- Mword count 2dup
- " (*" s=
- IF 2drop 1 + \ increment level count
- ELSE
- " *)" s=
- IF 1 - \ decrement level count
- ?dup 0EXIT \ and if zero, we're done
- THEN
- THEN
- AGAIN ; immediate
-
-
- \ We redefine a few useful words to take advantage of our optimization.
-
- : 1+ state IF 1 postpone literal postpone + ELSE 1 + THEN ; immediate
- : 2+ state IF 2 postpone literal postpone + ELSE 2 + THEN ; immediate
- : 3+ state IF 3 postpone literal postpone + ELSE 3 + THEN ; immediate
- : 4+ state IF 4 postpone literal postpone + ELSE 4 + THEN ; immediate
-
- : 1- state IF 1 postpone literal postpone - ELSE 1 - THEN ; immediate
- : 2- state IF 2 postpone literal postpone - ELSE 2 - THEN ; immediate
- : 3- state IF 3 postpone literal postpone - ELSE 3 - THEN ; immediate
- : 4- state IF 4 postpone literal postpone - ELSE 4 - THEN ; immediate
-
- : 2* state IF 1 postpone literal postpone << ELSE 1 << THEN ; immediate
- : 2/ state IF 1 postpone literal postpone a>> ELSE 1 a>> THEN ; immediate
- : 4* state IF 2 postpone literal postpone << ELSE 2 << THEN ; immediate
- : 4/ state IF 2 postpone literal postpone a>> ELSE 2 a>> THEN ; immediate
-
- \ ANSI words
-
- : CELL+ state IF postpone 4+ else 4 + THEN ; immediate
- : CELL- state IF postpone 4- else 4 - THEN ; immediate
- : CELLS state IF 2 postpone literal postpone << ELSE 2 << THEN ; immediate
- : CHAR+ state IF postpone 1+ else 1 + THEN ; immediate
- : CHARS ; immediate
-
- 4 constant 1CELL \ Not ANSI, but useful
-
-
- : RECURSE curr-def compile, ; immediate
-
- : SAVE-INPUT
- src-start src-len >in @ source-id 4 ;
-
- : RESTORE-INPUT
- dup 4 <> IF true EXIT THEN
- drop
- -> source-id >in ! -> src-len -> src-start false ;
-
-
- \ =========================
-
- \ These can be useful:
-
- : UMAX 2dup u> IF drop ELSE nip THEN ;
- : UMIN 2dup u< IF drop ELSE nip THEN ;
-
-
- \ .H and U.H print a number in hex, signed and unsigned respectively.
-
- : .H base >r hex . r> -> base ;
- : U.H base >r hex u. r> -> base ;
-
-
- 0 constant Z
-
- : NULLOSSTR ['] z ;
-
-
- : @WORD \ ( -- addr ) Retrieves next blank-delimited word from input stream.
- BL word ;
-
- : LIT \ ( n -- ) A state-smart version of LITERAL. Corresponds
- \ to LITERAL in Fig-Forth or original Neon, whereas our
- \ present LITERAL is Forth-83/ANSI.
- state IF postpone literal THEN ; immediate
-
- : 0, 0 , ; \ Compiles an empty cell
-
- : @VAL intrp1 ; \ Compiles a number from input stream
-
-
- : 'TYPE \ ( -- 4bytes ) OS type literal
- pad 4 bl fill @word count 4 min
- pad swap cmove pad @ postpone lit ; immediate
-
- create BUF255 256 allot \ buffer for string operations
-
- : >STR255 \ ( addr len addr -- addr )
- \ Converts a string to a Str255 at addr
- dup >r place r> ;
-
- : STR255 \ ( -- ^buf255 )
- buf255 >str255 ;
-
-
- : $ \ State-smart HEX literal word
- base >r
- hex Mword number postpone lit
- r> -> base ; immediate
-
-
- : LITW \ ( n -- )
- $ 3D3C w, w, ;
-
-
- : W intrp1 litw ; immediate
-
-
- (* Trap compilation. When we're fully native on the PowerPC this will
- become totally obsolete...
- *)
-
-
- : SAVA5 postpone doSavA5 ;
-
- : RSTA5
- $ CD4F w, \ exg a6,a7
- $ 2A5F w, ; \ move.l (a7)+,a5
-
- : (TRAP$) \ ( trap# -- ) Compiles a call to the given trap.
- SavA5 w, RstA5 ;
-
- : TRAP$ \ ( --<trap#> )
- base >r
- hex intrp1 (trap$)
- r> -> base ; immediate
-
-
- : (FDOS$) \ ( trap# -- )
- $ 205E w, \ move.l (a6)+,a0 ; FCB pointer
- SavA5 w, RstA5
- $ 48C0 w, \ ext.l d0 ; Result
- $ 2D00 w, ; \ move.l d0,-(a6)
-
-
- : FDOS$ \ ( --<trap#> )
- base >r
- hex intrp1 (fdos$)
- r> -> base ; immediate
-
-
- \ ==================
-
- \ Once we're compiling PPC code, we have to keep the code and data areas
- \ distinct. DP points to the data area, so we now add CDP pointing to
- \ the code area.
-
- 0 value CDP
-
- : code, PPC? IF CDP ! 4 ++> CDP ELSE , THEN ;
- : codeW, PPC? IF CDP w! 2 ++> CDP ELSE w, THEN ;
- : codeC, PPC? IF CDP c! 1 ++> CDP ELsE c, THEN ;
-
- ' null vect PPC_HEADER
-
-
- \ ==================
-
-
-
- 0 value ResRefNum
-
- : OpenResFile \ ( addr len -- ) Opens named resource file
- >r >r word0 r> r> str255
- trap$ a997 i->l \ call OpenResFile
- dup -> ResRefNum
- -1 = abort" resource file open failed" ;
-
- : CloseResFile \ ( -- )
- ResRefnum makeint trap$ a99a ;
-
-
- : OPENMR \ Opens the Mops system resource file if necessary.
- MRopen? ?EXIT \ Do nothing if already open
- instld? ?EXIT \ or if this is an installed application
- " mops.rsrc" OpenResFile
- true -> MRopen? ;
-
-
- : CHAR @word 1+ c@ ; \ ANSI - replaces ASCII
- : [CHAR] @word 1+ c@ postpone literal ; immediate
-
- : & \ ( -- c ) A shorter state-smart version.
- @word 1+ c@ postpone lit ; immediate
-
-
- : GETSTRING \ ( resID -- addr len ) Get the string with resource ID
- openMR
- 0 swap makeint trap$ a9ba \ call getString
- dup if @ count else 0 then ;
-
-
- : (TSTR) \ ( id# -- ) Prints string with given resID.
- getString type ;
-
- : X ['] (tstr) -> tstr ; \ We can't do -> outside a defn till Args loaded
- x forget x
-
-
- \ Our normal error action is to call DIE with an error number. DIE calls
- \ SvErr to save the error info, then THROWs the error number. If no error
- \ handler has been installed, or only handlers which don't want that number
- \ and re-THROW it, the default action for THROW occurs. This calls DFLT-DIE.
-
- : (DDIE) \ ( n -- )
- setFwind
- +echo 0 -> (err#) \ Clear error indicator from AppleEvents
- dflt-err ; \ Display error info and abort
-
- : x ['] (ddie) -> dflt-die ;
- x forget x
-
-
- : ?ERROR \ ( b -- ) Aborts and prints resource string if true.
- \ Usage: ?error 999
- postpone if
- intrp1 ( get err# ) postpone literal postpone die
- postpone then ; immediate
-
-
- : TYPE# \ Prints string for id# in stream
- intrp1 postpone lit postpone (tStr) ; immediate
-
-
- : (.RSTR) \ ( -- ) print "Msg# ..." then string with given resID
- ." Msg# " dup . ." : " (tStr) ;
-
-
- : MSG# \ usage: " Msg# <number>"
- intrp1 postpone lit postpone (.rStr) ; immediate
-
-
- \ ============ Resources ===========
-
-
- : GETRES \ ( type resID -- handle )
- 0 down makeint trap$ a9a0 ; \ call GetResource
-
-
- \ ( -- #cells)
-
- : RDEPTH rp0 rp@ - 4/ 2- ;
-
- : ?RDEPTH rp@ sp0 20 + < ?error 116 ; \ err if rtn stk about to
- \ collide with data stk
-
-
- \ ========== Type checking ===========
-
- \ Sometimes we want to check that a non-object parameter to a word is of a
- \ certain type. We give it a unique type code and use TYPCHK.
-
- : TYPCHK <> ?error 179 ;
-
-
- \ ========== Forward definitions ===========
-
-
- : X setfWind +echo
- cr ." From " r@ .id 2 spaces r@ .h cr 109 die ;
-
-
- : FORWARD
- colHdr
- $ 487AFFFE , \ pea (start of this instrn)
- ['] x here 6 allot
- (patch) ;
-
- : :F 301
- here ' (patch) :noname ;
-
- : ;F (;) 301 ?defn ; immediate
-
-
- forward BLD \ Used in CLASS. Needs to be down here so we never
- \ refer to it with a short branch. Kludge?
-
- \ Commonly needed error words. These are forward defined - the main
- \ application should provide a sensible definition, with a nice friendly
- \ alert box, to tell the user in a nice friendly way that things are up
- \ the creek.
-
- forward NOMEM \ Call when (not if!) we run out of memory.
-
- forward I/O_ERR \ ( err# -- ) Call when there's an I/O error.
-
- : OK? \ ( rc -- ) A useful word to use after an I/O op.
- ?dup 0EXIT I/O_err ;
-
-
- \ ========= :PROC and ;PROC ============
-
- : :PROC
- colHdr here 6 allot
- ['] procEntry swap 6 aligned_move
- :noname 303 ; immediate
-
- : ;PROC immediate
- postpone procExit (;)
- 303 ?defn ;
-
-
- \ ======== Various utility words needed later =========
-
- \ BECOME allows restarting at a given word, with all stacks
- \ empty. This is necessary in menu handlers and other areas
- \ that could create indefinite nesting situations.
-
- ' quit vect BECOMECFA
-
- : BE sp0 sp! rp0 rp! becomeCfa quit ;
-
- : (BE) -> becomeCfa be ;
-
-
- : BECOME \ Usage: Become newWord - compiles code to Be at runtime
- state
- IF postpone ['] postpone (be)
- ELSE ' -> becomeCfa be
- THEN ; immediate
-
-
- : DATETIME
- $ 20C @ ;
-
-
- \ ============ Tables, lists etc. ===============
-
- (* With Mops 2.5 we're trying to be consistent with the way we delimit
- various kinds of lists with { ... }. No, we're not trying to copy C,
- but let's at least follow the "principle of minimum astonishment"!
- Thus, with words like xts{, we'll allow a variant "xts {" where you
- can put a space before the "{". This is very easy to implement, so
- why not?
- *)
-
- forward { immediate
-
- : GOBBLE{ \ gobbles a "{" which must follow as a separate word.
- ' ['] { <> ?error 113 ; \ "{" expected
-
- : ) 123 die ; immediate \ ") read when no list is current"
- : (}) 123 die ; immediate \ "unmatched }"
-
- ' (}) vect } \ } will mean different things in different
- \ contexts.
-
- : }OR)? \ ( cfa -- cfa b )
- dup ['] } = over ['] ) = or ;
-
- (*
- : TABLE
- <BUILDS 0 w, here 112
- DOES> length ;
-
- : END_TABLE
- 112 ?pairs
- here over - \ table length (excluding length field)
- swap 2- w! ; \ store in length field
- *)
- 0 value CNT
-
-
- : (LITS) \ stack compiled list of values starting at IP
- w@(ip) ( count ) dup -> cnt
- 4* r> tuck + dup >r swap
- do i @abs 4 +loop
- cnt ;
-
-
- : XTS{ \ State-smart word to compile or stack a list
- \ of xts. Pulls words from stream, until "}".
- state IF postpone (lits) here 0 w, THEN
- 0
- BEGIN ' }or)?
- NWHILE state IF reloc, else swap THEN 1+
- REPEAT
- drop state IF swap w! THEN ; immediate
-
- : CFAS{ postpone xts{ ; immediate \ Synonyms for compatibility
- : CFAS( postpone xts{ ; immediate
-
- : XTS gobble{ postpone xts{ ; immediate
-
-
- : RESERVE \ ( len -- ) Allot and clear.
- here over erase allot ;
-
-
- (* SCON defines a string constant. Usage:
-
- scon <name> "a string"
-
- Runtime: ( -- addr len )
-
- Change from Neon: the first nonblank char after the name of the SCON
- becomes the delimiter. So " can be used as usual, but anything else can
- be used instead, e.g.:
-
- scon <name> /this string contains " as non-delimiter/
- *)
-
- : SCON
- <BUILDS bl skip-src+
- src-start >in @ + c@ ,dlm-str
- DOES> count ;
-
-
- \ CASE should be used for non-contiguous or dynamically computed values.
- \ This is a modified Eaker/Duncan model.
- \ Our optimization strategy gives quite good code.
-
- : CASE ?comp 302 ; immediate
-
- : OF
- postpone over postpone = postpone if
- postpone drop ; immediate
-
- : RANGEOF
- postpone within? postpone if
- postpone drop ; immediate
-
- : ENDOF
- postpone else ; immediate
-
- : ENDCASE immediate
- postpone drop
- BEGIN dup 302 = NWHILE >resolve REPEAT drop ;
-
- (* TYPE{ and ENUM{ (synonyms) define a Pascal/C-like enumerated type.
- At this stage we don't give a name to the "type" as such, as we can't
- do anything really sensible with it. However later we can optionally
- load the ENUM-TYPE class which is rather more Pascal-like. But even
- without that, the enumeration is very useful by itself.
- *)
-
- 0 value TYPECNT
-
- ' null vect DO_ET \ Hook for handling the ENUM-TYPE
- \ class when it's loaded
-
- : ENDLIST? \ ( chr -- b )
- latest n>count 1 = down c@ = and
- dup IF latest n>link (forget) THEN ;
-
-
- : TYPE{
- 0 -> typeCnt \ 1st value
- BEGIN typeCnt constant 1 ++> typeCnt
- & } endlist?
- UNTIL
- do_ET ;
-
- : ENUM{ type{ ; \ C fans might like this name better
- : ENUM gobble{ type{ ;
-
- \ note we can't allow "type { ..." since "type" has another
- \ meaning already. But "enum { ..." is OK.
-
- type{ InMainDic InOtherMod InThisMod } \ Relocatable addr types
-
-
- \ ========== Error diagnostics ===========
-
- \ We use special values for nil handles and nil pointers. These are
- \ odd addresses in ROM, so that if we do a word or long access we will
- \ trap, and if we write a byte it at least won't go anywhere.
-
-
- : .RTN \ ( addr -- )
- cr ." From $" .h 4 spaces ;
-
- : RANGE_ERR \ ( index range rtn-addr -- )
- dup 1+ 0= ?error 128 \ Spurious range error
- .rtn
- dup -1 <
- IF nip ?error 130 \ Not an indexed class
- ELSE ." Range: " . ." Index: " .
- true ?error 129
- THEN ;
-
-
- \ If we do software mult and div (on a 68000 which only allows a 16-bit divisor or
- \ multiplicand) we also check for overflow and call ArithErr (vector) if ovfl occurs.
- \ The appropriate err# is on the stack already, so here we just set ArithErr to Die.
- \ This can be redirected as needed.
-
- : X ['] range_err -> rngErr ['] die -> arithErr ;
-
- x forget x
-
- load Args
-